package com.whj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whj.domain.constants.SystemConstants;
import com.whj.domain.dto.UserDTO;
import com.whj.domain.entity.Role;
import com.whj.domain.entity.User;
import com.whj.domain.entity.UserRole;
import com.whj.domain.enums.AppHttpCodeEnum;
import com.whj.domain.response.ResponseResult;
import com.whj.domain.vo.PageVo;
import com.whj.domain.vo.RoleUserVO;
import com.whj.domain.vo.RoleVo;
import com.whj.domain.vo.UserInfoVo;
import com.whj.exception.SystemException;
import com.whj.mapper.RoleMapper;
import com.whj.mapper.UserMapper;
import com.whj.mapper.UserRoleMapper;
import com.whj.service.UserRoleService;
import com.whj.service.UserService;
import com.whj.utils.BeanCopyUtils;
import com.whj.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 用户表(User)表服务实现类
 *
 * @author wanghaijun
 * @since 2023-05-23 14:37:25
 */
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 查询用户信息
     *
     * @return
     */
    @Override
    public ResponseResult userinfo() {
        //获取用户当前id
        Long userId = SecurityUtils.getUserId();
        // 查询
        User user = getById(userId);
        // 封装
        UserInfoVo userInfoVo = BeanCopyUtils.copyBean(user, UserInfoVo.class);
        return ResponseResult.okResult(userInfoVo);
    }

    /**
     * 更新用户信息
     *
     * @param user
     * @return
     */
    @Transactional
    @Override
    public ResponseResult updateUserInfo(User user) {
        userMapper.updateById(user);
        List<String> roleIds = user.getRoleIds();
        if (!Objects.isNull(roleIds)){
            List<UserRole> userRoles = roleIds.stream()
                    .map(roleId->new UserRole(user.getId(),Long.parseLong(roleId)))
                    .collect(Collectors.toList());
            LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserRole::getUserId,user.getId());
            userRoleMapper.delete(queryWrapper);
            userRoleService.saveBatch(userRoles);
        }

        return ResponseResult.okResult();
    }

    @Autowired
    private UserRoleMapper userRoleMapper;

    /**
     * 用户注册
     *
     * @param user
     * @return
     */
    @Override
    @Transactional
    public ResponseResult register(User user) {
        //对数据进行非空判断
        if (!StringUtils.hasText(user.getUserName())) {
            throw new SystemException(AppHttpCodeEnum.USERNAME_NOT_NULL);
        }
        if (!StringUtils.hasText(user.getPassword())) {
            throw new SystemException(AppHttpCodeEnum.PASSWORD_NOT_NULL);
        }
        if (!StringUtils.hasText(user.getEmail())) {
            throw new SystemException(AppHttpCodeEnum.EMAIL_NOT_NULL);
        }
        if (!StringUtils.hasText(user.getNickName())) {
            throw new SystemException(AppHttpCodeEnum.NICKNAME_NOT_NULL);
        }
        //对数据存在是否判断
        if (userNameExist(user.getUserName())) {
            throw new SystemException(AppHttpCodeEnum.USERNAME_EXIST);
        }
        if (nickNameExist(user.getNickName())) {
            throw new SystemException(AppHttpCodeEnum.NICKNAME_EXIST);
        }
        if (emailExist(user.getEmail())) {
            throw new SystemException(AppHttpCodeEnum.EMAIL_EXIST);
        }
        //对密码进行加密
        String encode = passwordEncoder.encode(user.getPassword());
        user.setPassword(encode);
        user.setStatus(SystemConstants.STATUS_NORMAL);
        //存入数据库
        userMapper.insert(user);
        Long id = user.getId();
        //分配权限
        userRoleMapper.insert(new UserRole(id, SystemConstants.COMMON_ROLE));
        return ResponseResult.okResult();
    }


    /**
     * 列表查询
     *
     * @param pageNum
     * @param pageSize
     * @param username    用户名称
     * @param status
     * @param phoneNumber
     * @return
     */
    @Override
    public ResponseResult listRole(Integer pageNum, Integer pageSize, String phoneNumber, String username, String status) {

        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(username), User::getUserName, username);
        queryWrapper.eq(StringUtils.hasText(phoneNumber), User::getPhonenumber, phoneNumber);
        queryWrapper.eq(StringUtils.hasText(status), User::getStatus, status);

        Page<User> page = new Page<>(pageNum, pageSize);
        page(page, queryWrapper);

        return ResponseResult.okResult(new PageVo(page.getRecords(), page.getTotal()));
    }

    @Autowired
    private UserRoleService userRoleService;

    /**
     * 添加用户
     *
     * @param user
     * @return
     */
    @Transactional
    @Override
    public ResponseResult addUser(UserDTO user) {
        //对数据进行非空判断
        if (!StringUtils.hasText(user.getUserName())) {
            throw new SystemException(AppHttpCodeEnum.USERNAME_NOT_NULL);
        }
        if (!StringUtils.hasText(user.getPassword())) {
            throw new SystemException(AppHttpCodeEnum.PASSWORD_NOT_NULL);
        }
        if (!StringUtils.hasText(user.getEmail())) {
            throw new SystemException(AppHttpCodeEnum.EMAIL_NOT_NULL);
        }
        if (!StringUtils.hasText(user.getNickName())) {
            throw new SystemException(AppHttpCodeEnum.NICKNAME_NOT_NULL);
        }
        //对数据存在是否判断
        if (userNameExist(user.getUserName())) {
            throw new SystemException(AppHttpCodeEnum.USERNAME_EXIST);
        }
        if (nickNameExist(user.getNickName())) {
            throw new SystemException(AppHttpCodeEnum.NICKNAME_EXIST);
        }
        if (emailExist(user.getEmail())) {
            throw new SystemException(AppHttpCodeEnum.EMAIL_EXIST);
        }
        if (phoneExist(user.getPhonenumber())) {
            throw new SystemException(AppHttpCodeEnum.PHONENUMBER_EXIST);
        }
        User copyBean = BeanCopyUtils.copyBean(user, User.class);
        // 对密码加密
        String encode = passwordEncoder.encode(copyBean.getPassword());
        copyBean.setPassword(encode);
        // 添加角色
        userMapper.insert(copyBean);
        // 关联角色
        List<String> roleIds = user.getRoleIds();
        List<UserRole> userRoles = roleIds.stream()
                .map(roleId->new UserRole(copyBean.getId(),Long.parseLong(roleId)))
                .collect(Collectors.toList());
        userRoleService.saveBatch(userRoles);
        return ResponseResult.okResult();
    }

    /**
     * 删除用户信息
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult deleteUser(List<String> id) {
        Long userId = SecurityUtils.getUserId();
        if (userId.equals(id)){
            return ResponseResult.errorResult(AppHttpCodeEnum.NOT_ALLOW_USER);
        }
        List<Long> collect = id.stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
        userMapper.deleteBatchIds(collect);
        return ResponseResult.okResult();
    }

    @Autowired
    private RoleMapper roleMapper;
    /**
     *  根据id查询用户信息回显接口
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult selectUser(Long id) {

        RoleUserVO roleUserVO = new RoleUserVO();
        // 根据id获取 roleId
        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserRole::getUserId,id);
        List<UserRole> userRoles = userRoleMapper.selectList(queryWrapper);
        List<String> roleIds = new ArrayList<>();
        for (UserRole userRole : userRoles) {
            roleIds.add(String.valueOf( userRole.getRoleId()));
        }
        roleUserVO.setRoleIds(roleIds);

        // 查询所有role
        List<Role> roles = roleMapper.selectList(null);
        roleUserVO.setRoles(roles);

        // 获取用户信息
        User user = userMapper.selectById(id);
        roleUserVO.setUser(user);

        return ResponseResult.okResult(roleUserVO);
    }

    @Override
    @Transactional
    public ResponseResult changeStatus(RoleVo roleVo) {

        LambdaUpdateWrapper<User> queryWrapper = new LambdaUpdateWrapper<>();
        queryWrapper.eq(User::getId,roleVo.getUserId())
                .set(User::getStatus,roleVo.getStatus());
        userMapper.update(null,queryWrapper);
        return ResponseResult.okResult();
    }

    public boolean phoneExist(String phone){
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhonenumber, phone);
        Integer integer = userMapper.selectCount(queryWrapper);
        return integer > 0;
    }

    private boolean emailExist(String email) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, email);
        Integer integer = userMapper.selectCount(queryWrapper);
        return integer > 0;
    }

    private boolean nickNameExist(String nickName) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getNickName, nickName);
        Integer integer = userMapper.selectCount(queryWrapper);
        return integer > 0;
    }

    private boolean userNameExist(String userName) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserName, userName);
        Integer integer = userMapper.selectCount(queryWrapper);
        return integer > 0;
    }
}
